package org.celery.modules.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.celery.modules.goods.entity.Goods;
import org.celery.modules.goods.entity.GoodsStyle;
import org.celery.modules.goods.service.IGoodsService;
import org.celery.modules.order.entity.Order;
import org.celery.modules.order.enums.ShipTypeEnum;
import org.celery.modules.order.excel.OrderExcel;
import org.celery.modules.order.excel.OrderGoodsExcel;
import org.celery.modules.order.vo.OrderVO;
import org.celery.modules.order.mapper.OrderMapper;
import org.celery.modules.order.service.IOrderService;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.SecureUtil;
import org.springblade.core.tool.jackson.JsonUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.auth.utils.TokenUtil;
import org.springblade.modules.system.entity.Tenant;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.ITenantService;
import org.springblade.modules.system.service.IUserService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单表 服务实现类
 *
 * @author Celery
 * @since 2022-04-04
 */
@Service
@AllArgsConstructor
public class OrderServiceImpl extends BaseServiceImpl<OrderMapper, Order> implements IOrderService {

	private final IGoodsService goodsService;
	private final IUserService userService;

	@Override
	public IPage<OrderVO> selectOrderPage(IPage<OrderVO> page, OrderVO order) {
		return page.setRecords(baseMapper.selectOrderPage(page, order));
	}

	@Override
	public List<OrderExcel> exportOrder(Wrapper<Order> queryWrapper) {
		List<Order> orderList = baseMapper.selectList(queryWrapper);
		List<OrderExcel> orderExcelList = new ArrayList<>();

		List<Goods> goodsList = goodsService.list();

		for (Order order : orderList) {
			OrderExcel orderExcel = new OrderExcel() {{
				setTotalAmount(order.getTotalAmount().toString());
				setGoodsName("");
				setRemark(order.getRemark());
				setReceiveName(order.getReceiverName());
				setReceiveTelephone(order.getReceiverPhone());
			}};

			List<GoodsStyle> goodsStyleList = JsonUtil.parseArray(order.getAssociatedGoods(), GoodsStyle.class);
			for (GoodsStyle goodsStyle : goodsStyleList) {
				for (Goods goods: goodsList) {
					if (goods.getId().equals(goodsStyle.getGoodsId())) {
						// 商品名仅显示一次
						if (Func.isEmpty(orderExcel.getGoodsName())) {
							orderExcel.setGoodsName(goods.getName());
						}
					}
				}
				if (Func.isEmpty(orderExcel.getRemark())) {
					orderExcel.setRemark(goodsStyle.getValue() + " * 1;  ");
				} else {
					orderExcel.setRemark(orderExcel.getRemark() + (orderExcel.getGoodsName().equals("") ? (goodsStyle.getValue() + " * 1") : (goodsStyle.getValue() + "; * 1")));
				}
			}
			orderExcelList.add(orderExcel);
		}
		return orderExcelList;
	}

	@Override
	public List<OrderGoodsExcel> exportOrderGoods(Wrapper<Order> queryWrapper) {
		List<Order> orderList = baseMapper.selectList(queryWrapper);
		List<OrderGoodsExcel> orderGoodsExcelList = new ArrayList<>();

		List<Goods> goodsList = goodsService.list();

		for (Order order : orderList) {
			List<GoodsStyle> goodsStyleList = JsonUtil.parseArray(order.getAssociatedGoods(), GoodsStyle.class);
			for (GoodsStyle goodsStyle : goodsStyleList) {
				String goodsName = null;
				// 设置商品名
				for (Goods goods: goodsList) {
					if (goods.getId().equals(goodsStyle.getGoodsId())) {
						goodsName = goods.getName();
					}
				}
				// 如果记录为空,直接追加一条记录
				if (Func.isEmpty(orderGoodsExcelList)) {
					String finalGoodsName = goodsName;
					orderGoodsExcelList.add(new OrderGoodsExcel() {{
						setStyle(goodsStyle.getValue());
						setCount(1);
						setGoodsName(finalGoodsName);
					}});
				} else {
					boolean match = false;
					for (OrderGoodsExcel orderGoodsExcel: orderGoodsExcelList) {
						if (Func.isNotEmpty(goodsName) && orderGoodsExcel.getGoodsName().equals(goodsName) && orderGoodsExcel.getStyle().equals(goodsStyle.getValue())) {
							orderGoodsExcel.setCount(orderGoodsExcel.getCount()+1);
							match = true;
							break;
						}
					}
					if (!match) {
						String finalGoodsName1 = goodsName;
						orderGoodsExcelList.add(new OrderGoodsExcel() {{
							setGoodsName(finalGoodsName1);
							setStyle(goodsStyle.getValue());
							setCount(1);
						}});
					}
				}
			}
		}
		return orderGoodsExcelList;
	}

	@Override
	public String getOrderCode() {
		String today = DateUtil.formatDate(DateUtil.now());
		Date startTime = DateUtil.parse(today + " 00:00:00", DateUtil.PATTERN_DATETIME);
		Date endTime = DateUtil.parse(today + " 23:59:59", DateUtil.PATTERN_DATETIME);

		// 获取今日该租户订单
		QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().between(Order::getCreateTime, startTime, endTime);
		queryWrapper.lambda().eq(Order::getTenantId, TokenUtil.DEFAULT_TENANT_ID);

		List<Order> orderList = list(queryWrapper);

		NumberFormat nf = new DecimalFormat("0000");

		return DateUtil.format(DateUtil.now(), "yyyyMMdd") + nf.format(orderList.size() + 1) ;
	}

	@Override
	public QueryWrapper<Order> getQueryWrapper(Order order, BladeUser bladeUser) {
		QueryWrapper<Order> queryWrapper = Condition.getQueryWrapper(order);
		queryWrapper.lambda().orderByAsc(Order::getShipStatus).orderByDesc(Order::getCreateTime);
		if (Func.isNotEmpty(order.getReceiverName())) {
			queryWrapper.lambda().like(Order::getReceiverName, order.getReceiverName());
			order.setReceiverName(null);
		}
		if (Func.isNotEmpty(order.getReceiverPhone())) {
			queryWrapper.lambda().like(Order::getReceiverPhone, order.getReceiverPhone());
			order.setReceiverPhone(null);
		}
		if (Func.isNotEmpty(order.getCode())) {
			queryWrapper.lambda().like(Order::getCode, order.getCode());
			order.setCode(null);
		}

		if (!SecureUtil.isAdministrator()) {
			queryWrapper.lambda().eq(Order::getTenantId, bladeUser.getTenantId());

			List<User> allUnderUserList = userService.getUnderUserIdList(bladeUser);
			queryWrapper.lambda().in(
					Order::getFromUser,
					allUnderUserList.stream().map(User::getId).collect(Collectors.toList())
			);
		}
		return queryWrapper;
	}

	@Override
	public List<Map<String, Object>> topAmountGroupByUser(int topUserInt) {
		return baseMapper.topAmountGroupByUser(topUserInt);
	}

}
